import regeneratorRuntime from '../resource/libs/runtime'
import { server_origin, server_base_path, company_id } from './config'
import { wxApiPromise, syncCacheCurrentUrl } from './utils'

let app = getApp()
let loginPromise
const service = {
  /**发起 https 请求；
   * header 头信息带上 token，从 app.global_data 中拿；
   * 当请求超时或服务器出错向用户弹出提示并返回 null；
   * 只有 data.errorCode 为 0 时才表示请求成功，返回 data 数据；
   * 否则根据 errorCode 处理特殊业务逻辑：
   * 1.10001 为 token 失效；
   * 2.其他统一认为请求错误，打印错误信息并返回 errorCode；
   * @param {Object} options 和 wx.request 接口传参基本一致，
   *                         除了传 url 改为传 server_api
   *                         （服务器 api 接口，比如获取 token 的接口为 token/user）
   * @returns 请求超时或服务器出错返回 null，请求成功返回 data 数据，请求错误返回 errorCode
   */
  async asyncRequest (options) {
    let { server_api, url, header = {}, ...other } = options
    if (!server_api) {
      throw new Error('缺少 server_api 参数，请查阅 server.asyncRequest 方法')
    }
    let token = app.global_data.token
    if (!token && server_api !== 'token/user'){
      if(!loginPromise){
        loginPromise = this.asyncLogin()
      }
      await loginPromise
      loginPromise = null
    }
    wx.showNavigationBarLoading()
    let res = await wxApiPromise(wx.request, {
      url: server_origin + server_base_path + server_api,
      header: Object.assign({ token }, header),
      ...other
    })
    wx.hideNavigationBarLoading()
    let { data = {}, statusCode } = res
    if (!res || statusCode !== 200) { // 请求超时或服务器出错
      await wxApiPromise(wx.showModal, {
        title: '请求超时',
        content: '',
        showCancel: false
      })
      return null
    }
    let { errorCode = 0, msg } = data
    errorCode = Number(errorCode)
    if (errorCode === 0) {
      return data
    } else if (errorCode === 10001) { // 处理 token 失效
      if(!loginPromise){
        loginPromise = this.asyncLogin()
      }
      await loginPromise
      loginPromise = null
      return await this.asyncRequest(options)
    } else { // 其他统一认为请求错误
      console.error('服务器接口', server_api, '请求错误：', msg)
      return errorCode
    }
  },

  /**发起 get 请求
   * @param {String} server_api 请求的服务器 api 接口，比如获取 token 的接口为 token/user
   * @param {String|Object|Arraybuffer} [data={}] 发送的数据
   * @returns Promise 对象
   */
  getPromise (server_api, data = {}) {
    return this.asyncRequest({
      server_api,
      data,
      method: 'GET'
    })
  },

  // 发起 post 请求，同上
  postPromise (server_api, data = {}) {
    return this.asyncRequest({
      server_api,
      data,
      method: 'POST'
    })
  },

  // 处理登录业务
  async asyncLogin () {
    let wx_login_res = await wxApiPromise(wx.login)
    wx_login_res = wx_login_res || {}
    let { code } = wx_login_res
    let server_login_data = await this.getPromise('token/user', { code, company_id })
    if (!server_login_data || typeof server_login_data === 'number') {
      return
    }
    let { data, errorCode } = server_login_data
    let { token, phone, type } = data
    // 更新 global_data
    app.updateGlobalData({ token, phone })
    // 服务器未存储用户微信资料时，进行授权并存储
    if (type === 2) {
      let if_save = await this.asyncGetUserInfo()
      console.log('if_save', if_save)
      if (!if_save) {
        //app.updateGlobalData({ token: '' })
        return
      }
    }
  },

  // 处理授权获取用户微信资料
  async asyncGetUserInfo () {
    if (wx.canIUse('button.open-type.getUserInfo')) {
      let wx_setting_res = await wxApiPromise(wx.getSetting)
      if (!wx_setting_res.authSetting['scope.userInfo']) {
        // 先缓存当前页面的 url 信息
        syncCacheCurrentUrl()
        wx.redirectTo({
          url: '/pages/authorize/index?auth_type=userinfo',
        })
        throw new Error('跳转信息授权页面，中断当前页面的业务')
      }
    } else { // 没有 open-type=getUserInfo 的版本
      let wx_userinfo_res = await wxApiPromise(wx.getUserInfo, {
        withCredentials: true,
        lang: 'zh_CN'
      })
      let { encryptedData, iv } = wx_userinfo_res
      let res = await this.postPromise('user/info', { encryptedData, iv })
      if (!res) { return false }
      if (typeof res === 'number') {
        wx.showModal({
          title: '资料获取失败',
          showCancel: false
        })
        return false
      }
      return true
    }
  },

  /**处理授权获取用户当前地理位置业务；
   * 如果强制用户必须授权，则当用户拒绝授权时，跳转信息授权页引导用户授权；
   * @param {Boolean} [if_must=false] 是否强制必须授权
   * @returns 同意授权返回地理位置对象，拒绝授权返回 null
   */
  async asyncGetLocation (if_must = false) {
    let res = await wxApiPromise(wx.getLocation, {
      type: 'gcj02'
    })
    if (!res && if_must) {
      // 先同步缓存当前页面的 url 信息
      syncCacheCurrentUrl()
      wx.redirectTo({
        url: '/pages/authorize/index?auth_type=location',
      })
      throw new Error('跳转信息授权页面，中断当前页面的业务')
    }
    return res
  },
}

export default service
